home *** CD-ROM | disk | FTP | other *** search
- /*
- buffer I/O
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define TRUE 1
- #define FALSE 0
- #define ERR (-1)
-
- #define PTR(p) (unsigned int)(p)
- #define unlink remove
- #define MAX_BUF (16384-24)
-
- #define HEAD_SIZ (sizeof(BUF_PTR)-MAX_BUF)
- #define SEEK_POS(n) ((long)(n)*sizeof(BUF_PTR))
-
- #define WRITE_ERR 1
- #define READ_ERR 2
-
- typedef struct _BP {
- struct _BP *next;
- int alno;
- int left;
- int right;
- int len;
- int lfc;
- char buf[MAX_BUF];
- } BUF_PTR;
-
- typedef struct _EP {
- struct _EP *next;
- int actno;
- int actpos;
- long pos;
- long line;
- } EDT_PTR;
-
- extern void wrtstr();
- extern int Input();
- extern char *Tmp_device_name;
-
- EDT_PTR *edt_top=NULL;
-
- static EDT_PTR *undo_edt=NULL;
- static long undo_sz=0L;
- static FILE *tfp=NULL;
- static int free_no=ERR;
- static BUF_PTR *top_ptr=NULL;
- static char TMPFILE[80];
-
- unsigned long int Freemem()
- {
- int mx;
- unsigned long int sz,fm;
- char *dmy[128];
-
- for ( sz = 0x10000,fm = mx = 0 ; mx < 128 ; mx++ ) {
- while ( (dmy[mx] = malloc(sz)) == NULL ) {
- if ( (sz /= 2) < 0x1000 )
- break;
- }
- if ( dmy[mx] == NULL )
- break;
- fm += sz;
- }
- while ( mx > 0 )
- free(dmy[--mx]);
- return fm;
- }
- int Bfp_init()
- {
- int i;
- BUF_PTR *bp;
- char *p;
- unsigned long int l;
-
- l = Freemem() / 2;
- i = l / sizeof(BUF_PTR);
-
- if ( (bp = (BUF_PTR *)malloc(sizeof(BUF_PTR)*i)) == NULL )
- return ERR;
-
- top_ptr = bp;
- for ( i-- ; i > 0 ; i-- ) {
- bp->next = bp + 1;
- bp->alno = ERR;
- bp++;
- }
- bp->next = NULL;
- bp->alno = ERR;
-
- if ( (p = Tmp_device_name) != NULL ||
- (p = getenv("TMP")) != NULL )
- sprintf(TMPFILE,"%s\\",p);
- else
- TMPFILE[0] = '\0';
- strcat(TMPFILE,"WINK.TMP");
-
- New_link();
- undo_edt = edt_top;
- New_link();
-
- return FALSE;
- }
- void Bfp_end()
- {
- if ( tfp != NULL ) {
- fclose(tfp);
- unlink(TMPFILE);
- }
- }
- static void retry(no)
- int no;
- {
- static char *msg[]={
- "Save Temp Seek Error ",
- "Save Temp Write Header Error",
- "Save Temp Write Buffer Error",
- "Load Temp Seek Error ",
- "Load Temp Read Header Error ",
- "Save Temp Read Buffer Error ",
- "New Temp File Can't open ",
- "New Temp Write Error ",
- "Temp File Can't open "
- };
- int i;
- FILE *fp;
- char tmp[80];
- char buf[512];
-
- RETRY:
- do {
- wrtstr(msg[no],30,1,0x12);
- tmp[0] = '\0';
- while ( (short int)Input(tmp,"テンポラリドライブ名 ") != FALSE );
- if ( strcmp(tmp,"EXIT") == 0 )
- exit(10);
- strcat(tmp,"\\WINK.TMP");
- wrtstr(" ",30,1,0x1F);
- no = 6;
- } while ( (fp = fopen(tmp,"w+b")) == NULL );
-
- if ( tfp != NULL ) {
- fseek(tfp,0L,SEEK_SET);
- while ( (i = fread(buf,1,512,tfp)) > 0 )
- fwrite(buf,1,i,fp);
- }
-
- if ( ferror(fp) ) {
- fclose(fp);
- unlink(tmp);
- no = 7;
- goto RETRY;
- }
-
- if ( tfp != NULL ) {
- fclose(tfp);
- unlink(TMPFILE);
- }
-
- tfp = fp;
- strcpy(TMPFILE,tmp);
- }
- static void save_buf(bp)
- register BUF_PTR *bp;
- {
- if ( tfp == NULL && (tfp = fopen(TMPFILE,"w+b")) == NULL ) {
- retry(8);
- goto RETRY;
- }
- RETRY:
- if ( fseek(tfp,SEEK_POS(bp->alno),SEEK_SET) ) {
- retry(0);
- goto RETRY;
- }
- if ( fwrite((char *)bp,HEAD_SIZ,1,tfp) < 1 ) {
- retry(1);
- goto RETRY;
- }
- if ( bp->len > 0 && fwrite(bp->buf,1,bp->len,tfp) < bp->len ) {
- retry(2);
- goto RETRY;
- }
- }
- static void load_buf(no,bp)
- int no;
- register BUF_PTR *bp;
- {
- BUF_PTR *tp;
-
- if ( tfp == NULL && (tfp = fopen(TMPFILE,"w+b")) == NULL ) {
- retry(8);
- goto RETRY;
- }
- RETRY:
- if ( fseek(tfp,SEEK_POS(no),SEEK_SET) ) {
- retry(3);
- goto RETRY;
- }
- tp = bp->next;
- if ( fread((char *)bp,HEAD_SIZ,1,tfp) < 1 ) {
- bp->next = tp;
- retry(4);
- goto RETRY;
- }
- bp->next = tp;
- if ( bp->len > 0 && fread(bp->buf,1,bp->len,tfp) < bp->len ) {
- retry(5);
- goto RETRY;
- }
- }
- static BUF_PTR *get_buf(no)
- int no;
- {
- BUF_PTR *tp;
- register BUF_PTR *bp;
-
- bp = top_ptr;
- while ( bp->alno != no ) {
- if ( bp->next == NULL ) {
- if ( bp->alno != ERR )
- save_buf(bp);
- if ( no != ERR )
- load_buf(no,bp);
- break;
- }
- tp = bp;
- bp = bp->next;
- }
- if ( bp != top_ptr ) {
- tp->next = bp->next;
- bp->next = top_ptr;
- top_ptr = bp;
- }
- return bp;
- }
- static int xalloc()
- {
- static int alno=0;
- register BUF_PTR *bp;
-
- if ( free_no != ERR ) {
- bp = get_buf(free_no);
- free_no = bp->left;
- } else {
- bp = get_buf(ERR);
- bp->alno = alno++;
- }
- bp->left = bp->right = ERR;
- bp->len = 0;
- bp->lfc = ERR;
- return bp->alno;
- }
- static void xfree(no)
- int no;
- {
- register BUF_PTR *bp;
-
- bp = get_buf(no);
- bp->left = free_no;
- free_no = no;
- bp->len = 0;
- }
- static int link_buf(no)
- int no;
- {
- int new;
- BUF_PTR *tp;
- BUF_PTR *bp;
-
- new = xalloc();
- tp = get_buf(no); /* 1 */
- bp = get_buf(new); /* 2 */
-
- bp->left = no;
- bp->right = tp->right;
- tp->right = new;
-
- if ( bp->right != ERR ) {
- tp = get_buf(bp->right); /* 3 */
- tp->left = new;
- }
- return new;
- }
- static void del_buf(no)
- int no;
- {
- BUF_PTR *tp;
- BUF_PTR *bp;
-
- bp = get_buf(no);
- if ( bp->left != ERR ) {
- tp = get_buf(bp->left);
- tp->right = bp->right;
- }
- if ( bp->right != ERR ) {
- tp = get_buf(bp->right);
- tp->left = bp->left;
- }
- xfree(no);
- }
- static int line_count(bp)
- register BUF_PTR *bp;
- {
- int i,n;
- register char *p;
-
- if ( bp->lfc == ERR ) {
- p = bp->buf;
- n = 0;
- for ( i = bp->len ; i > 0 ; i-- ) {
- if ( *(p++) == '\n' )
- n++;
- }
- bp->lfc = n;
- }
- return bp->lfc;
- }
- static char *chk_ptr(ep,pos)
- register EDT_PTR *ep;
- long pos;
- {
- BUF_PTR *bp;
-
- bp = get_buf(ep->actno);
- while ( (ep->pos + bp->len) < pos ) {
- if ( bp->right == ERR )
- return &(bp->buf[bp->len]);
- ep->actno = bp->right;
- ep->pos += bp->len;
- ep->line += line_count(bp);
- bp = get_buf(ep->actno);
- }
- while ( ep->pos > pos ) {
- if ( bp->left == ERR )
- return bp->buf;
- ep->actno = bp->left;
- bp = get_buf(ep->actno);
- ep->pos -= bp->len;
- ep->line -= line_count(bp);
- }
- return &(bp->buf[(int)(pos - ep->pos)]);
- }
- static long get_line(ep,line)
- register EDT_PTR *ep;
- int *line;
- {
- int t;
- int n,i;
- char *p;
- BUF_PTR *bp;
-
- bp = get_buf(ep->actno);
- while ( (ep->line + line_count(bp)) < *line ) {
- if ( bp->right == ERR ) {
- *line = ep->line + line_count(bp);
- break;
- }
- ep->actno = bp->right;
- ep->pos += bp->len;
- ep->line += line_count(bp);
- bp = get_buf(ep->actno);
- }
- while ( ep->line >= *line ) {
- if ( bp->left == ERR ) {
- *line = ep->line;
- break;
- }
- ep->actno = bp->left;
- bp = get_buf(ep->actno);
- ep->pos -= bp->len;
- ep->line -= line_count(bp);
- }
-
- p = bp->buf;
- t = n = *line - ep->line;
- i = 0;
- while ( n > 0 && i < bp->len ) {
- if ( *(p++) == '\n' )
- n--;
- i++;
- }
- *line -= n;
-
- return (ep->pos + (long)i);
- }
- char *Cnv_ptr(pos)
- long pos;
- {
- register EDT_PTR *ep;
- register BUF_PTR *bp;
-
- ep = edt_top;
- bp = get_buf(ep->actno);
- while ( (ep->pos + bp->len) <= pos ) {
- if ( bp->right == ERR )
- return &(bp->buf[bp->len]);
- ep->actno = bp->right;
- ep->pos += bp->len;
- ep->line += line_count(bp);
- bp = get_buf(ep->actno);
- }
- while ( ep->pos > pos ) {
- if ( bp->left == ERR )
- return bp->buf;
- ep->actno = bp->left;
- bp = get_buf(ep->actno);
- ep->pos -= bp->len;
- ep->line -= line_count(bp);
- }
- return &(bp->buf[(int)(pos - ep->pos)]);
- }
- static int ins_str(ep,pos,str,n)
- EDT_PTR *ep;
- long pos;
- char *str;
- int n;
- {
- int tn,i,len;
- BUF_PTR *tp;
- BUF_PTR *bp;
- char *p;
- static char tmp[MAX_BUF];
-
- p = chk_ptr(ep,pos);
- bp = get_buf(ep->actno);
- if ( (tn = &bp->buf[bp->len] - p) > 0 ) {
- memcpy(tmp,p,tn);
- bp->len -= tn;
- }
-
- len = n + tn;
- for ( ; len > 0 ; ) {
- if ( bp->len >= MAX_BUF ) {
- bp = get_buf(link_buf(bp->alno));
- p = bp->buf;
- }
-
- if ( n == 0 ) {
- n = tn;
- str = tmp;
- }
-
- i = PTR(&(bp->buf[MAX_BUF])) - PTR(p);
- if ( i > n ) i = n;
-
- memcpy(p,str,i);
- p += i;
- str += i;
- n -= i;
- len -= i;
- bp->len += i;
- bp->lfc = ERR;
- }
-
- if ( bp->right != ERR ) {
- tp = get_buf(bp->right);
- if ( (bp->len + tp->len) < MAX_BUF ) {
- memcpy(&bp->buf[bp->len],tp->buf,tp->len);
- bp->len += tp->len;
- bp->lfc = ERR;
- del_buf(bp->right);
- }
- }
-
- return FALSE;
- }
- static int del_str(ep,pos,len)
- EDT_PTR *ep;
- long pos;
- int len;
- {
- int i,n;
- BUF_PTR *tp;
- BUF_PTR *bp;
- char *p;
-
- p = chk_ptr(ep,pos);
- bp = get_buf(ep->actno);
-
- for ( ; len > 0 ; ) {
- n = &bp->buf[bp->len] - p;
- if ( n <= len ) {
- bp->len -= n;
- len -= n;
- } else {
- memcpy(p,p+len,n-(int)len);
- bp->len -= len;
- len = 0;
- }
- bp->lfc = ERR;
- if ( bp->len == 0 && bp->right != ERR ) {
- if ( (i = bp->alno) == ep->actno )
- ep->actno = bp->right;
- bp = get_buf(bp->right);
- del_buf(i);
- } else if ( len > 0 && bp->right != ERR ) {
- bp = get_buf(bp->right);
- } else
- break;
- p = bp->buf;
- }
-
- if ( bp->right != ERR ) {
- tp = get_buf(bp->right);
- if ( (bp->len + tp->len) < MAX_BUF ) {
- memcpy(&bp->buf[bp->len],tp->buf,tp->len);
- bp->len += tp->len;
- bp->lfc = ERR;
- del_buf(bp->right);
- }
- }
-
- return FALSE;
- }
- static int cut_str(ep,pos,str,n)
- EDT_PTR *ep;
- long pos;
- char *str;
- int n;
- {
- int i,len;
- BUF_PTR *bp;
- char *p;
-
- p = chk_ptr(ep,pos);
- bp = get_buf(ep->actno);
-
- for ( len = 0 ; n > 0 ; ) {
- i = &bp->buf[bp->len] - p;
- if ( i > n ) i = n;
- memcpy(str,p,i);
- str += i;
- n -= i;
- len += i;
- if ( n > 0 ) {
- if ( bp->right == ERR )
- break;
- bp = get_buf(bp->right);
- p = bp->buf;
- }
- }
-
- return len;
- }
- long Line_ptr(n)
- int *n;
- {
- return get_line(edt_top,n);
- }
- void Ins_buf(ptr,sz,str)
- long ptr;
- int sz;
- char *str;
- {
- ins_str(edt_top,ptr,str,sz);
- }
- void Del_buf(ptr,sz)
- long ptr;
- long sz;
- {
- int n;
-
- while ( sz > 0 ) {
- n = (sz > 16384 ? 16384:sz);
- del_str(edt_top,ptr,n);
- sz -= n;
- }
- }
- void Cut_buf(str,sz,ptr)
- char *str;
- int sz;
- long ptr;
- {
- cut_str(edt_top,ptr,str,sz);
- }
- int New_link()
- {
- EDT_PTR *ep;
-
- if ( (ep = (EDT_PTR *)malloc(sizeof(EDT_PTR))) == NULL )
- return ERR;
-
- ep->next = edt_top;
- edt_top = ep;
-
- ep->actno = xalloc();
- ep->pos = 0L;
- ep->line = 0;
-
- return FALSE;
- }
- void Kill_link(ep)
- EDT_PTR *ep;
- {
- int no;
- BUF_PTR *bp;
-
- no = ep->actno;
- for ( ; ; ) {
- bp = get_buf(no);
- if ( bp->left == ERR )
- break;
- no = bp->left;
- }
- while ( no != ERR ) {
- bp = get_buf(no);
- no = bp->right;
- xfree(bp->alno);
- }
- free(ep);
- }
- long Nxt_line(pos)
- long pos;
- {
- int i;
- char *p;
- register EDT_PTR *ep;
- register BUF_PTR *bp;
- extern long btm_ptr;
-
- p = Cnv_ptr(pos);
- ep = edt_top;
- bp = get_buf(ep->actno);
- do {
- while ( p >= &(bp->buf[bp->len]) ) {
- if ( bp->right == ERR ) {
- p = &(bp->buf[bp->len]);
- goto ENDOF;
- }
- i = PTR(p) - PTR(&(bp->buf[bp->len]));
- ep->actno = bp->right;
- ep->pos += bp->len;
- ep->line += line_count(bp);
- bp = get_buf(ep->actno);
- p = &(bp->buf[i]);
- }
- } while ( *(p++) != '\n' );
- ENDOF:
- pos = (ep->pos + (long)(PTR(p) - PTR(bp->buf)));
- return (pos > btm_ptr ? btm_ptr : pos);
- }
- void Undo_put(ptr,sz)
- long ptr,sz;
- {
- int n;
- char tmp[256];
-
- while ( undo_sz > 0 ) {
- n = (undo_sz > 16384 ? 16384:undo_sz);
- del_str(undo_edt,0L,n);
- undo_sz -= n;
- }
- while ( sz > 0 ) {
- n = (sz > 256 ? 256:sz);
- cut_str(edt_top,ptr,tmp,n);
- ins_str(undo_edt,undo_sz,tmp,n);
- sz -= n;
- ptr += n;
- undo_sz += n;
- }
- }
- long Undo_get(ptr)
- long ptr;
- {
- int n;
- long sz,pos;
- char tmp[256];
-
- sz = undo_sz;
- pos = 0L;
- while ( sz > 0 ) {
- n = (sz > 256 ? 256:sz);
- cut_str(undo_edt,pos,tmp,n);
- ins_str(edt_top,ptr,tmp,n);
- sz -= n;
- pos += n;
- ptr += n;
- }
- return undo_sz;
- }
- int Undo_cpy(buf,sz,pos)
- char *buf;
- int sz;
- long pos;
- {
- return cut_str(undo_edt,pos,buf,sz);
- }